var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var disco;
(function (disco) {
    (function (model) {
        /// <reference path="../typings/jquery/jquery.d.ts" />
        /// <reference path="../typings/knockout/knockout.d.ts" />
        /// <reference path="../disco/disco.model.ts" />
        (function (helper) {
            var DataContextManager = (function () {
                function DataContextManager(dataContext) {
                    this.dataContext = dataContext;
                }
                DataContextManager.prototype.getDataContext = function () {
                    return this.dataContext;
                };

                DataContextManager.prototype.setDataContext = function (context) {
                    this.dataContext = context;
                };

                DataContextManager.prototype.getMetadata = function () {
                    return this.getDataContext().metadata;
                };

                //public getEntityTypeCollection(): EntityType[] {
                //    return this.getDataContext().entityTypes;
                //}
                //public getEntitySetCollection(): EntitySet[] {
                //    return this.getDataContext().entitySets;
                //}
                DataContextManager.prototype.generateEntityModel = function () {
                    this.generateEntityTypes();
                    this.generateEntitySets();
                };

                DataContextManager.prototype.generateEntitySets = function () {
                    var _this = this;
                    var context = this.getDataContext();
                    var metaEntitySets = this.getEntitySetsMetadata();

                    metaEntitySets.forEach(function (metaEntitySet) {
                        var setTypeName = disco.Namespace.remove(metaEntitySet.entityType);

                        var set = new model.EntitySet();
                        set.name = metaEntitySet.name;
                        set.type = _this.getDataContext().entityType(setTypeName);
                        set.type.entitySet = set;

                        _this.getDataContext().entitySet(set.type.name, set);
                    });
                };

                DataContextManager.prototype.generateEntityTypes = function () {
                    this.generateBasicEntityTypes();
                    this.applyBaseTypes();
                    this.addNavigationToEntityProperties();
                };

                DataContextManager.prototype.generateBasicEntityTypes = function () {
                    var _this = this;
                    var associations = this.getAssociationsMetadata();
                    var typeMgr = new model.EntityTypeManager();

                    this.getEntityTypesMetadata().forEach(function (metaEntityType) {
                        typeMgr.setEntityType();
                        typeMgr.generateSimpleProperties(metaEntityType, associations);

                        var type = typeMgr.getEntityType();
                        _this.getDataContext().entityType(type.name, type);
                    });
                };

                DataContextManager.prototype.applyBaseTypes = function () {
                    var _this = this;
                    var typeMgr = new model.EntityTypeManager();

                    Object.keys(this.getDataContext().entityTypes).forEach(function (key) {
                        typeMgr.setEntityType(_this.getDataContext().entityTypes[key]);
                        typeMgr.applyBaseType(_this.getDataContext());
                    });
                };

                DataContextManager.prototype.addNavigationToEntityProperties = function () {
                    var _this = this;
                    var typeMgr = new model.EntityTypeManager();

                    Object.keys(this.getDataContext().entityTypes).forEach(function (key) {
                        typeMgr.setEntityType(_this.getDataContext().entityTypes[key]);
                        typeMgr.addNavigationToEntityProperties(_this.getDataContext());
                    });
                };

                DataContextManager.prototype.getEntityTypesMetadata = function () {
                    return this.getMetadataServices().schema[0].entityType;
                };
                DataContextManager.prototype.getAssociationsMetadata = function () {
                    return this.getMetadataServices().schema[0].association;
                };
                DataContextManager.prototype.getEntitySetsMetadata = function () {
                    var dataServices;
                    var schemaIndex = (this.getMetadataServices().schema.length > 1) ? 1 : 0;
                    return this.getMetadataServices().schema[schemaIndex].entityContainer[0].entitySet;
                };

                DataContextManager.prototype.getMetadataServices = function () {
                    return this.getMetadata().dataServices;
                };
                return DataContextManager;
            })();
            helper.DataContextManager = DataContextManager;
            var EntitySetManager = (function (_super) {
                __extends(EntitySetManager, _super);
                function EntitySetManager() {
                    _super.apply(this, arguments);
                }
                EntitySetManager.prototype.add = function (entity) {
                    if (!disco.Collections.contains(this.get().rows(), function (e) {
                        return e.prop('Id').value == entity.prop('Id').value;
                    }))
                        this.get().rows.push(entity);
                };
                return EntitySetManager;
            })(disco.core.DataManager);
            helper.EntitySetManager = EntitySetManager;
            var EntityManager = (function (_super) {
                __extends(EntityManager, _super);
                function EntityManager(context) {
                    _super.call(this);
                    this.context = context;
                }
                //creates Entity from raw disco.web request data
                EntityManager.prototype.fromRawEntity = function (rawEntity) {
                    var entity = this.set(new model.Entity());

                    var typeString = disco.Namespace.remove(rawEntity['odata.type']);
                    entity.type = this.context.entityType(typeString);
                    entity.type.properties.forEach(function (property) {
                        var propertyValue = new disco.model.PropertyValue();
                        propertyValue.property = property;
                        if (property.isNavigation) {
                            //propertyValue.loaded = false;
                            propertyValue.url = rawEntity[property.name + '@odata.navigationLinkUrl'];
                        } else {
                            //propertyValue.loaded = true;
                            propertyValue.value = rawEntity[property.name];
                        }
                        entity.prop(property.name, propertyValue);
                    });

                    return entity;
                };
                return EntityManager;
            })(disco.core.DataManager);
            helper.EntityManager = EntityManager;
        })(model.helper || (model.helper = {}));
        var helper = model.helper;
    })(disco.model || (disco.model = {}));
    var model = disco.model;
})(disco || (disco = {}));
